package com.etung.iot.demo.storage.constorage;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.etung.iot.demo.dao.ConditionStorageMapper;
import com.etung.iot.demo.dao.RealDataMapper;
import com.etung.iot.demo.modles.ConditionStorageEntity;
import com.etung.iot.demo.modles.RealData;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class ConditionStorageUtil {
    @Autowired
    private ConditionStorageMapper conditionStorageMapper;
    @Autowired
    private RealDataMapper realDataMapper;

    private static final String CONDITION_CACHE_PREFIX = "condition:";

    //生产环境请使用redis
    private static Map<String, Map<Integer, List<ConditionStorageEntity>>> storageMap = new ConcurrentHashMap<>();
    //上次存储时间
    private static Map<String, Long> lastStoreMap = new ConcurrentHashMap<>();

    /**
     * 倒排查找当前变量的监控变量规则集合
     *
     * @param imei
     * @param targetVarId
     * @return
     */
    public Map<Integer, List<ConditionStorageEntity>> getConditionStorageRule(String imei, Integer targetVarId) {
        String key = imei + "_" + targetVarId;
        Map<Integer, List<ConditionStorageEntity>> res;
        if (!storageMap.containsKey(key)) {
            res = Maps.newHashMap();
            List<ConditionStorageEntity> conditionStorageEntityList = conditionStorageMapper.selectList(new QueryWrapper<ConditionStorageEntity>().eq("imei", imei));
            if (conditionStorageEntityList != null && conditionStorageEntityList.size() > 0) {
                List<ConditionStorageEntity> conditionStorageList = Lists.newArrayList();
                conditionStorageEntityList.forEach(conditionStorageEntity -> {
                    String varIdListStr = conditionStorageEntity.getVarIdList();
                    if (!StringUtils.isEmpty(varIdListStr)) {
                        List<String> targetVarIdList = Arrays.asList(varIdListStr.split(","));
                        if (targetVarIdList.contains(targetVarId)) {
                            conditionStorageList.add(conditionStorageEntity);
                        }
                    }
                    res.put(targetVarId, conditionStorageList);
                });
            }
            storageMap.put(key, res);
        } else {
            res = storageMap.get(key);
        }
        return res;
    }

    public List<ConditionStorageEntity> getConditionStorageByTargetVarId(String imei, Integer targetVarId) {
        Map<Integer, List<ConditionStorageEntity>> conditionStorageRuleMap = getConditionStorageRule(imei, targetVarId);
        if (conditionStorageRuleMap != null && conditionStorageRuleMap.containsKey(targetVarId)) {
            return conditionStorageRuleMap.get(targetVarId);
        }
        return null;
    }

    public void removeConditionStorageRule(String imei) {
        storageMap.entrySet().removeIf(entry -> entry.getKey().startsWith(imei));
        lastStoreMap.entrySet().removeIf(entry -> entry.getKey().startsWith(imei));
    }

    public Long getLastStoreTimestamp(String imei, Integer varId) {
        String key = CONDITION_CACHE_PREFIX + imei + "_" + varId;
        Long res = 0L;
        if (lastStoreMap.containsKey(key)) {
            res = lastStoreMap.get(key);
        } else {
            RealData realData = realDataMapper.selectOne(
                    new QueryWrapper<RealData>()
                            .eq("imei", imei).eq("variant_id", varId)
                            .orderByDesc("`time`").last("limit 1")

            );
            if (realData != null) {
                res = realData.getTime().getTime();
                lastStoreMap.put(key, res);
            }
        }
        return res;
    }

    public void saveLastStoreTimestamp(String imei, Integer varId, Long timestamp) {
        String key = CONDITION_CACHE_PREFIX + imei + "_" + varId;
        lastStoreMap.put(key, timestamp);
    }


}
